#include "AsioIOServicePool.h"

AsioIOServicePool::~AsioIOServicePool()
{
	std::cout << "destruct AsioIOServicePool......" << std::endl;
}

AsioIOServicePool::AsioIOServicePool(size_t size) : m_nextIOService(0), m_ioServices(size), m_works(size)
{
	for (int i = 0; i < size; ++i) {
		m_works[i] = std::unique_ptr<Work>(new Work(m_ioServices[i]));
	}

	// 遍历每个boost::asio::io_context，让每个线程里面都跑一个boost::asio::io_context
	for (int i = 0; i < m_ioServices.size(); ++i) {
		m_threads.emplace_back([this, i]() {
			m_ioServices[i].run();
		});
	}
}

boost::asio::io_context& AsioIOServicePool::getIOService()
{
	// 依次轮询
	auto& service = m_ioServices[m_nextIOService++];
	if (m_nextIOService == m_ioServices.size()) {
		m_nextIOService = 0;
	}

	return service;
}

void AsioIOServicePool::stop()
{
	// 仅仅执行work.reset并不能让iocontext从run的状态中退出
	// 当iocontext已经绑定了读或写的监听事件后，还需要手动stop该服务。
	for (auto& work : m_works) {
		work->get_io_context().stop();
		work.reset();
	}

	for (auto& t : m_threads) {
		t.join();
	}
}
